#!/bin/bash -e
#   * compile instructions: put this file in
#   *         `steamapps/common/Dyson Sphere Program/CustomMod`
#   * folder, open a terminal in the same folder, and execute:
#   *
#   * ```
#   *     chmod +x ${file}.cs
#   *     ./${file}.cs
#   * ```
#   *
#   * then the mod will be compiled automatically.
#   *
#   * Here we wrote a shebang like file, which is correct
#   * in my computer (Manjaro XFCE), if such script do not work
#   * in your computer, you could just try the instructions below :
#region shell_script
if [ -z "$__DOTNET_CSC" ]; then
    export __DOTNET_CSC="`find /usr/share/dotnet -type f -name dotnet` `find /usr/share/dotnet -name csc.dll`"
    echo '$'"__DOTNET_CSC not set yet, you should execute"
    echo "export __DOTNET_CSC='$__DOTNET_CSC'"
    echo "manually, or this alert will occur each time you execute this script."
fi

__MODE_VERBOSE=81 # is the line number of "#define VERBOSE", may be modified
__MODE_DEBUG__=$((__MODE_VERBOSE+1))
__MODE_RELEASE=$((__MODE_DEBUG__+1))

case $1 in
    V)       _MODE__SELECT_=$__MODE_VERBOSE     ;;
    v)       _MODE__SELECT_=$__MODE_VERBOSE     ;;
    VERBOSE) _MODE__SELECT_=$__MODE_VERBOSE     ;;
    verbose) _MODE__SELECT_=$__MODE_VERBOSE     ;;
    D)       _MODE__SELECT_=$__MODE_DEBUG__     ;;
    d)       _MODE__SELECT_=$__MODE_DEBUG__     ;;
    DEBUG)   _MODE__SELECT_=$__MODE_DEBUG__     ;;
    debug)   _MODE__SELECT_=$__MODE_DEBUG__     ;;
    *)       _MODE__SELECT_=$__MODE_RELEASE     ;;
esac

export GAME_NAME="${0%\.cs}" # now, file name should be equals to ${GAME_NAME}.cs, the benefit is, we could only change the name, rather than change filename and $GAME_NAME.
export GAME_NAME="game"
export FILE_NAME="$0"
export ASSEMBLY="Assembly-CSharp"
export GAME_BASE_DIR="common/ChineseParent"
export PLUGIN_ID="Neutron3529.ChineseParent"
export NAMESPACE_ID="Neutron3529.ChineseParent"

( yes "" | head -n $_MODE__SELECT_ | head -n-1  ; tail $FILE_NAME -n+$_MODE__SELECT_ ) | sed s/%%NAMESPACE_ID%%/${NAMESPACE_ID}/g | sed s/%%PLUGIN_ID%%/${PLUGIN_ID}/g | $__DOTNET_CSC -nologo -t:library \
  -r:"${GAME_BASE_DIR}/BepInEx/core/BepInEx.dll" \
  -r:"${GAME_BASE_DIR}/BepInEx/core/0Harmony.dll" \
  -r:"${GAME_BASE_DIR}/BepInEx/core/BepInEx.Harmony.dll" \
  `[ -e "${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/netstandard.dll" ] && echo "-r:\"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/netstandard.dll\""` \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/System.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/System.Core.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/UnityEngine.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/UnityEngine.CoreModule.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/mscorlib.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/Assembly-CSharp.dll" \
  -out:"${GAME_BASE_DIR}/BepInEx/plugins/${FILE_NAME%.*}".dll \
  -optimize -deterministic `[ "$_MODE__SELECT_" == "$__MODE_DEBUG__" ] && echo -debug` \
  - && rm -f "${GAME_BASE_DIR}/BepInEx/config/${PLUGIN_ID}.cfg";

if [ -n "$2" ]; then
    git add ${FILE_NAME}
    case $2 in
        R) git commit -am "`curl -s https://whatthecommit.com/index.txt`" ;;
        r) git commit -am "`curl -s https://whatthecommit.com/index.txt`" ;;
        RANDOM) git commit -am "`curl -s https://whatthecommit.com/index.txt`" ;;
        random) git commit -am "`curl -s https://whatthecommit.com/index.txt`" ;;
        U) git commit -am "`curl -s https://whatthecommit.com/index.txt`" ;;
        u) git commit -am "`curl -s https://whatthecommit.com/index.txt`" ;;
        UPLOAD) git commit -am "`curl -s https://whatthecommit.com/index.txt`" ;;
        upload) git commit -am "`curl -s https://whatthecommit.com/index.txt`" ;;
        *) git commit -am "$2" ;;
    esac
    git push
fi
exit

#endregion
#define VERBOSE // the line of __MODE_VERBOSE
#define DEBUG



using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;

using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

namespace %%NAMESPACE_ID%%
{
    [BepInPlugin("%%PLUGIN_ID%%", "%%NAMESPACE_ID%%", "0.1.0")]
    public class Cheat : BaseUnityPlugin {
        private static Action<string> _logger=s=>{};//用于内联代码
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static void logger(string s,string extra_id=""){
#if DEBUG
            _logger(extra_id+":"+s);
#endif
        }
        public static Harmony harmony=new Harmony("%%PLUGIN_ID%%");
        public static float mul=100f;
        void Awake() {
#if DEBUG
            _logger=Logger.LogInfo;
#endif
            logger("开始注入Awake");
            if(Config.Bind("config", "naodongTryDoMagicEffect", true, "脑洞大爆炸").Value){
                logger("patch naodongTryDoMagicEffect");
                harmony.PatchAll(typeof(naodongTryDoMagicEffect));
                logger("naodongTryDoMagicEffect patched");
            }
            if((mul=Config.Bind("config", "BrainMgrNaodongAddValue", mul, "脑洞层数加成").Value)>1f){
                logger("patch BrainMgrNaodongAddValue");
                harmony.PatchAll(typeof(BrainMgrNaodongAddValue));
                logger("BrainMgrNaodongAddValue patched");
            }
            if(Config.Bind("config", "NewTrickMgrTryAddTrickByRate", true, "100%获得新特性").Value){
                logger("patch NewTrickMgrTryAddTrickByRate");
                harmony.PatchAll(typeof(NewTrickMgrTryAddTrickByRate));
                logger("NewTrickMgrTryAddTrickByRate patched");
            }
            if(Config.Bind("config", "NewTrickMgrGetFaceFightList", true, "使用最优而非随机trick").Value){
                logger("patch NewTrickMgrGetFaceFightList");
                harmony.PatchAll(typeof(NewTrickMgrGetFaceFightList));
                logger("NewTrickMgrGetFaceFightList patched");
            }
            if(Config.Bind("config", "NewFaceRewardMgrFaceRewardFetchTimes", true, "索取次数永不耗尽").Value){
                logger("patch NewFaceRewardMgrFaceRewardFetchTimes");
                harmony.PatchAll(typeof(NewFaceRewardMgrFaceRewardFetchTimes));
                logger("NewFaceRewardMgrFaceRewardFetchTimes patched");
            }
            if(Config.Bind("config", "WorkWndDoFightValueAdd", true, "其实打工非常赚钱……").Value){
                logger("patch WorkWndDoFightValueAdd");
                harmony.PatchAll(typeof(WorkWndDoFightValueAdd));
                logger("WorkWndDoFightValueAdd patched");
            }
            if(Config.Bind("config", "LovingValue", true, "大家都是爱你的").Value){
                logger("patch LovingValue");
                harmony.PatchAll(typeof(NewSocialGirlMgrBeginDate));
                harmony.PatchAll(typeof(NewSocialBoyMgrBeginDate));
                logger("LovingValue patched");
            }
            if(Config.Bind("config", "WaitForSecondsConstructor", true, "10倍速？").Value){
                logger("patch WaitForSecondsConstructor");
                harmony.PatchAll(typeof(WaitForSecondsConstructor));
                logger("WaitForSecondsConstructor patched");
            }
            logger("Awake完成");
        }
        //脑洞大爆炸
        [HarmonyPatch(typeof(naodong), "TryDoMagicEffect")]
        public static class naodongTryDoMagicEffect
        {
            private static bool Prefix(ref naodong __instance, ref int ___m_magicType)
            {
                if (___m_magicType == 0 || ___m_magicType == 9 || ___m_magicType == 11)
                {
                    __instance.DoMagic_random();
                    ___m_magicType = 2;
                }
                return true;
            }
        }
        //脑洞层数加成
        [HarmonyPatch(typeof(BrainMgr), "NaodongAddValue",MethodType.Getter)]
        public static class BrainMgrNaodongAddValue
        {
            private static float Postfix(float __result)
            {
                return __result*mul;
            }
        }
        //修改学习获得trick的几率
        [HarmonyPatch(typeof(NewTrickMgr), "TryAddTrickByRate")]
        public static class NewTrickMgrTryAddTrickByRate
        {
            private static bool Prefix(ref int _trickRate)
            {
                _trickRate=100;
                return true;
            }
        }
        // Trick优选法
        [HarmonyPatch(typeof(NewTrickMgr), "GetFaceFightList")]
        public static class NewTrickMgrGetFaceFightList
        {
            private static bool Prefix(ref List<int> __result,NewTrickMgr __instance)
            {
                List<int> list;
                if (__instance.LearnedTrickes.Count < 9)
                {
                    list = new List<int>(__instance.LearnedTrickes);
                }
                else
                {
                    list = new List<int>();
                    //IEnumerable<TableFaceFightImmunity> source = from item in SingleTon<TableMgr>.Instance.TableFaceFightImmunity.GetItemList() where item.Type == this.m_fightID select item;
                    List<int> list2 = (from x in __instance.LearnedTrickes orderby /*source.Any((TableFaceFightImmunity item) => item.Tip1 == x)?-8:*/-SingleTon<TableMgr>.Instance.TableTrick.GetItem(x).Attack select x).ToList<int>();
                    for (int i = 0; i < 9; i++)
                    {
                        int index = 0;
                        list.Add(list2[index]);
                        list2.RemoveAt(index);
                    }
                }
                __result=list;
                return false;
            }
        }/*
        [HarmonyPatch(typeof(TableFaceReward), "Weight", MethodType.Getter)]
        public static class TableFaceRewardWeight
        {
            private static float Postfix(float __result)
            {
                return __result+10000f;
            }
        }*/
        [HarmonyPatch(typeof(NewFaceRewardMgr), "FaceRewardFetchTimes", MethodType.Getter)]
        public static class NewFaceRewardMgrFaceRewardFetchTimes
        {
            private static int Postfix(int __result)
            {
                return Mathf.Max(__result,1);
            }
        }
        [HarmonyPatch(typeof(WorkWnd), "DoFightValueAdd")]//这里不是在修改迭代器，这里是在玩一个更花的活。
        public static class WorkWndDoFightValueAdd
        {
            private static void Postfix(ref float ___m_fightingValue)
            {
                ___m_fightingValue=(float)(100*((int)___m_fightingValue/100+1));
            }
        }
        [HarmonyPatch(typeof(NewSocialGirlMgr), "BeginDate")]
        public static class NewSocialGirlMgrBeginDate
        {
            private static void Postfix(ref int ___m_alertValue,ref List<NewSocialGirlNpcInfo> ___m_infos)
            {
                ___m_alertValue=0;
                foreach(var x in ___m_infos){
                    x.LovingValue = Mathf.Max(x.LovingValue,90);
                }
            }
        }
        [HarmonyPatch(typeof(NewSocialBoyMgr), "BeginDate")]
        public static class NewSocialBoyMgrBeginDate
        {
            private static void Postfix(ref int ___m_alertValue,ref List<NewSocialGirlNpcInfo> ___m_npcInfos)
            {
                ___m_alertValue=0;
                foreach(var x in ___m_npcInfos){
                    x.LovingValue = Mathf.Max(x.LovingValue,90);
                }
            }
        }
        [HarmonyPatch(typeof(WaitForSeconds),MethodType.Constructor)]
        public static class WaitForSecondsConstructor
        {
            private static bool Prefix(ref float seconds)
            {
                seconds*=0.1f;
                return true;
            }
        }
    }
}
